package cn.j0n4than.accountingtool.controller.api.auth;

import cn.j0n4than.accountingtool.config.ResponseConfig;
import cn.j0n4than.accountingtool.entity.Active;
import cn.j0n4than.accountingtool.entity.User;
import cn.j0n4than.accountingtool.pojo.Auth;
import cn.j0n4than.accountingtool.pojo.request.UserLoginRequest;
import cn.j0n4than.accountingtool.pojo.request.UserRegRequest;
import cn.j0n4than.accountingtool.utils.Response;
import cn.j0n4than.accountingtool.utils.StrUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.mail.MessagingException;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * 用户授权控制器
 *
 * @author jonathan
 */
@Slf4j
@RestController
@RequestMapping("/api/auth/user")
public class AuthUserController extends AuthBaseController {

    /**
     * 用户登陆接口
     *
     * @return Json
     */
    @PostMapping("/login")
    public Response login(
            @Validated @RequestBody UserLoginRequest userLoginRequest,
            BindingResult bindingResult,
            HttpServletRequest request
    ) {
        Response response = Response.response();

        //检查验证器的错误
        checkValidate(response, bindingResult);
        if (response.getStatus() == ResponseConfig.ERROR) {
            return response;
        }

        User user = this.userService.login(userLoginRequest.username, userLoginRequest.password);

        if (user != null) {
            //未激活不让登陆
            if (user.emailVerifiedAt == null) {
                return response.setStatus(ResponseConfig.ERROR).setMessage("账号未验证邮箱");
            }
            //验证密码成功
            try {
                Auth auth = new Auth();
                auth.userId = user.id;
                auth.ip = request.getRemoteAddr();
                auth.type = Auth.TYPE_USER;
                String json = this.objToJsonStr(auth);

                //加密token
                String token = desUtil.encrypt(json);

                //不返回密码
                user.password = null;

                //更新登陆信息
                user.lastLoginAt = new Date(System.currentTimeMillis());
                user.lastLoginIp = getClientIp(request);
                userService.update(user.id, user);

                //存入token到redis
                if (!redisUtil.set(Integer.toString(user.id), token, Auth.DAY)) {
                    return response.setStatus(ResponseConfig.ERROR).setMessage("登陆失败, 请联系管理员");
                }

                response.setStatus(ResponseConfig.SUCCESS)
                        .setMessage("登陆成功")
                        .setResult("user", user)
                        .setResult("token", token);
            } catch (JsonProcessingException e) {
                response.setStatus(ResponseConfig.ERROR)
                        .setMessage("用户名或密码错误");

                log.error("加密Token失败");
                log.error(e.getMessage());
            }
        } else {
            response.setStatus(ResponseConfig.ERROR)
                    .setMessage("用户名或密码错误");
        }

        return response;
    }

    /**
     * 用户注册接口
     *
     * @param userRegRequest 请求体
     * @param bindingResult  验证结果
     * @return Response
     */
    @PostMapping("/reg")
    public Response reg(
            @Validated @RequestBody UserRegRequest userRegRequest,
            BindingResult bindingResult
    ) {
        Response response = Response.response();

        //检查验证器的错误
        checkValidate(response, bindingResult);
        if (response.getStatus() == ResponseConfig.ERROR) {
            return response;
        }

        if (!userRegRequest.password.equals(userRegRequest.conPassword)) {
            response.setStatus(ResponseConfig.ERROR)
                    .setMessage("两次输入的密码必须保持一致");
            return response;
        }

        //检查是否用户名重名
        User userByUsername = userService.getUserByUsername(userRegRequest.username);
        if (userByUsername != null) {
            return response.setStatus(ResponseConfig.ERROR).setMessage("该用户名不可用");
        }

        //注册逻辑
        User reg = this.userService.reg(userRegRequest.username, userRegRequest.password, userRegRequest.email);

        //注册成功
        if (reg != null) {
            response.setStatus(ResponseConfig.SUCCESS).setMessage("注册成功,请查看邮箱完成验证来激活您的账号");

            //插入激活数据表
            Active active = new Active();
            active.userId = reg.id;
            active.id = StrUtil.getRandomString(64);
            this.activeService.insert(active);

            //发送验证邮箱的地址
            String url = this.siteUrl + "auth/active/" + active.id;

            //发送邮件
            try {
                mailUtil.mimeMessageSend("激活您的账号", userRegRequest.email, "<a href=\"" + url + "\">点击我激活</a>");
            } catch (MessagingException e) {
                log.info("注册成功邮件发送失败");
            }
        } else {
            //注册失败
            response.setStatus(ResponseConfig.ERROR).setMessage("注册失败");
        }
        return response;
    }
}
